<!-- eslint-disable no-prototype-builtins -->
<!-- eslint-disable no-prototype-builtins -->
<template>
  <div class="setting-panel fd-pa-8">
    <el-tabs v-model="state.activeTab" style="overflow: hidden;">
      <el-tab-pane label="组件配置" name="组件配置">
        <el-scrollbar :height="state.scrollHeight">
          <el-form
            :model="designer.getSeletedWidgetOptions()"
            label-position="left"
            label-width="85px"
          >
            <el-collapse v-model="state.activeCollapse">
              <el-collapse-item
                :key="index"
                v-for="(propertyList, index) in state.widgetPropertyLists"
                :title="propertyList.name"
                :name="index"
              >
                <div
                  v-for="propKey in propertyList.propertys"
                  :key="Math.random() + propKey"
                >
                  <!-- 当前组件存在该属性才展示对应的属性编辑器 -->
                  <component
                    :key="Math.random() + propKey"
                    v-if="hasEditProp(propKey)"
                    :is="getEditorName(propKey)"
                    :optionModel="designer.selectedWidget.options"
                    :designer="designer"
                    :widget="designer.selectedWidget"
                    @editEventProp="editEventProp"
                  ></component>
                </div>
              </el-collapse-item>
            </el-collapse>
          </el-form>
        </el-scrollbar>
      </el-tab-pane>
      <el-tab-pane label="表单配置" name="表单配置">
        <el-scrollbar :height="state.scrollHeight">
          <el-form label-position="left" label-width="85px">
            <el-collapse v-model="state.activeCollapse">
              <el-collapse-item
                :key="index"
                v-for="(propertyList, index) in state.formPropertyLists"
                :title="propertyList.name"
                :name="index"
              >
                <div v-for="propKey in propertyList.propertys" :key="propKey">
                  <component
                    :is="getEditorName(propKey)"
                    :optionModel="designer.formConfig"
                    :designer="designer"
                    @editEventProp="editEventProp"
                  ></component>
                </div>
              </el-collapse-item>
            </el-collapse>
          </el-form>
        </el-scrollbar>
      </el-tab-pane>
    </el-tabs>
    <!-- 事件属性编辑器 -->
    <div v-if="state.showCodeDialog">
      <CodeEditorDialog
        :designer="designer"
        v-model:code="state.optionModel[state.codeDialogTitle]"
        v-model:showCodeDialog="state.showCodeDialog"
        :title="state.codeDialogTitle"
        :tip="state.codeDialogTip"
      />
    </div>
  </div>
</template>
<script setup>
import { onMounted, reactive, inject, computed } from 'vue'
import CommPropEditors from './property-editor/commProp/index.js'
import EventEditors from './property-editor/eventProp/index.js'
import { COMMON_PROPERTIES, EVENT_PROPERTIES } from './propertyRegister.js'
import CodeEditorDialog from './components/codeEditorDialog.vue'
const designer = inject('designer')

defineOptions({
  components: {
    ...CommPropEditors,
    ...EventEditors,
  },
})
const state = reactive({
  optionModel: computed(() => {
    if (state.activeTab === '组件配置') {
      return designer.selectedWidget?.options
    } else {
      return designer.formConfig
    }
  }),
  activeTab: '组件配置',
  activeCollapse: 0,
  scrollHeight: 0,
  widgetPropertyLists: [
    {
      name: '普通属性',
      propertys: [],
    },
    {
      name: '事件属性',
      propertys: [],
    },
  ],
  formPropertyLists: [
    {
      name: '普通属性',
      propertys: [],
    },
    {
      name: '事件属性',
      propertys: [],
    },
  ],
  showCodeDialog: false, // 事件属性展示编辑器
  codeDialogTitle: '',
  codeDialogTip: '',
})

const getEditorName = (name) => {
  // 判断是否有以该物料type为前缀的属性组件，有则返回该组件，若没有则使用通用属性组件
  const editorName = `${designer.selectedWidget?.type}-${name}-editor`
  const hasComponent = CommPropEditors[editorName] ?? EventEditors[editorName]
  if (hasComponent) return editorName
  return name + '-editor'
}
const hasEditProp = (name) => {
  const editorName = getEditorName(name)
  return !!(CommPropEditors[editorName] ?? EventEditors[editorName])
}
// 获取当前选中组件的属性编辑组件
const getPropertys = () => {
  const options = designer.getSeletedWidgetOptions()
  // eslint-disable-next-line no-prototype-builtins
  const commonProp = Object.keys(options).filter((item) =>
    COMMON_PROPERTIES.includes(item),
  )
  // eslint-disable-next-line no-prototype-builtins
  const eventProp = Object.keys(options).filter((item) =>
    EVENT_PROPERTIES.includes(item),
  )
  state.widgetPropertyLists[0].propertys = commonProp
  state.widgetPropertyLists[1].propertys = eventProp
}
// 初始化表单配置
const initFormPropertys = () => {
  const commonProp = Object.keys(designer.formConfig).filter(
    (item) => !!COMMON_PROPERTIES.includes(item),
  )
  const eventProp = Object.keys(designer.formConfig).filter(
    (item) => !!EVENT_PROPERTIES.includes(item),
  )
  state.formPropertyLists[0].propertys = commonProp
  state.formPropertyLists[1].propertys = eventProp
}
// 计算滚动条高度
const computedHeight = () => {
  state.scrollHeight = window.innerHeight - 75 + 'px'
}

const addEventsListener = () => {
  // 监听选中物料事件触发，用于更新当前物料的属性编辑器
  window.addEventListener('select_widget', getPropertys)
  window.addEventListener('resize', computedHeight)
}

// 点击事件属性编写代码按钮时触发
const editEventProp = ({ title, tip }) => {
  state.showCodeDialog = true
  state.codeDialogTitle = title
  state.codeDialogTip = tip
}
onMounted(() => {
  addEventsListener()
  initFormPropertys()
  computedHeight()
})
</script>
<style lang="less" scoped>
:deep(.el-tabs__content) {
  border-top: 1px solid #ccc;
}
:deep(.el-form-item) {
  margin-bottom: 5px;
}
:deep(.el-form-item__label) {
  font-size: 12px;
}
</style>
